package com.yuyou.fn.analyze.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.analyze.service.IBusinessStatisticsService;
import com.yuyou.fn.analyze.service.IDataStatisticsService;
import com.yuyou.fn.analyze.service.IGradeAndSubjectStatisticsService;
import com.yuyou.fn.analyze.service.IProductStatisticsService;
import com.yuyou.fn.analyze.vo.*;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.service.ISiteConfigService;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.Utils;
import com.yuyou.fn.educational.entity.*;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.educational.vo.CourseClassQueryVo;
import com.yuyou.fn.platform.entity.BusTeam;
import com.yuyou.fn.platform.entity.SysUser;
import com.yuyou.fn.platform.service.IBusTeamService;
import com.yuyou.fn.report.entity.CostOfGradeSubject;
import com.yuyou.fn.report.entity.RealIncomeOfClass;
import com.yuyou.fn.report.service.ICostOfGradeSubjectService;
import com.yuyou.fn.report.service.IRealIncomeOfClassService;
import com.yuyou.fn.report.vo.*;
import com.yuyou.fn.settlement.entity.ChangeRecord;
import com.yuyou.fn.settlement.service.IChangeRecordService;
import com.yuyou.fn.settlement.vo.FeeCategoryTreeMapVo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

import static com.yuyou.fn.settlement.constant.FeeCategoryEnum.SALARY_OF_COURSE;

/**
 * ProductTarget 表数据服务层接口实现类
 */
@Service
public class GradeAndSubjectStatisticsServiceImpl implements IGradeAndSubjectStatisticsService {
    @Resource
    private IBaseGradeService baseGradeService;

    @Resource
    private IBaseSubjectService baseSubjectService;

    @Resource
    private IBusinessStatisticsService businessStatisticsService;

    @Resource
    private IProductStatisticsService productStatisticsService;

    @Resource
    private ICourseClassService courseClassService;

    @Resource
    private IBusTeamService busTeamService;

    @Resource
    private IChangeRecordService changeRecordService;

    @Resource
    private ISiteConfigService siteConfigService;

    @Resource
    private IClassLectureService classLectureService;

    @Resource
    private IDataStatisticsService dataStatisticsService;

    @Resource
    private ICostOfGradeSubjectService costOfGradeSubjectService;

    @Resource
    private IRealIncomeOfClassService realIncomeOfClassService;

    @Resource
    private IStudentRegService studentRegService;

    @Override
    public List<GradeAndSubjectCostAndIncomeVo> findCostAndIncomeList(Long areaTeamId,  Date startDate, Date endDate,Long gradeId,Long subjectId) {
        if (startDate.getTime()>endDate.getTime()){
            throw new BusException("开始时间必须小于等于结束时间");
        }
        String mainAccountFeeCategory = siteConfigService.getConfigValueFromCache("grade_subject_feeCategory");
        List<FeeCategoryTreeMapVo> allFeeCategoryTreeMapVoList = JSONArray.parseArray(mainAccountFeeCategory, FeeCategoryTreeMapVo.class);

        List<GradeAndSubjectCostAndIncomeVo> gradeAndSubjectCostAndIncomeVoList=new ArrayList<GradeAndSubjectCostAndIncomeVo>();
        List<BusTeam> busTeamList=busTeamService.findBusTeamByAreaTeamIds(Arrays.asList(areaTeamId));
        List<Long> busTeamIdList= BeanUtils.toList(busTeamList,"busTeamId");
        busTeamIdList=productStatisticsService.filterBusTeamByPermissions(busTeamIdList);
        List<BaseGrade> baseGradeList=null;
        if (gradeId!=null){
            baseGradeList=baseGradeService.findByIds(Arrays.asList(gradeId));
        }else {
            baseGradeList=baseGradeService.findAllFromCache();
        }
        List<BaseSubject> baseSubjectList=null;
        if (subjectId!=null){
            baseSubjectList=baseSubjectService.findByIds(Arrays.asList(subjectId));
        }else {
            baseSubjectList=baseSubjectService.findAllFromCache();
        }

        List<GradeAndSubjectClassVo> gradeAndSubjectClassVoList=this.findGradeAndSujectBusTeamClassLeature(busTeamIdList,baseGradeList,baseSubjectList,startDate,endDate);
        List<CourseClass> allBusTeamClass=courseClassService.findSimpByBusTeamIds(busTeamIdList,"classId","busTeamId");
        List<Long> classIdList = BeanUtils.toList(allBusTeamClass, "classId");
        List<ClassLecture> classLectureList = classLectureService.findByClassIdAndTime(classIdList, startDate, endDate,1,"classId","classDate");
        List<BusTeamClassVo> busTeamClassVoList=productStatisticsService.findBusTeamsClassLeature(busTeamIdList,allBusTeamClass,classLectureList,startDate,endDate);
        Map<Long,BusTeamClassVo> busTeamClassMap=BeanUtils.toMap(busTeamClassVoList,"busTeamId");
        List<Long> feeCategoryIdList=new ArrayList<Long>();
        businessStatisticsService.fillAllFeeCategoryId(feeCategoryIdList,allFeeCategoryTreeMapVoList);
        for (GradeAndSubjectClassVo gradeAndSubjectClassVo:gradeAndSubjectClassVoList){
            GradeAndSubjectCostAndIncomeVo gradeAndSubjectCostAndIncomeVo=new GradeAndSubjectCostAndIncomeVo();
            gradeAndSubjectCostAndIncomeVo.setGradeId(gradeAndSubjectClassVo.getGradeId());
            gradeAndSubjectCostAndIncomeVo.setGradeName(gradeAndSubjectClassVo.getGradeName());
            gradeAndSubjectCostAndIncomeVo.setSubjectId(gradeAndSubjectClassVo.getSubjectId());
            gradeAndSubjectCostAndIncomeVo.setSubjectName(gradeAndSubjectClassVo.getSubjectName());
            BigDecimal cost=BigDecimal.ZERO;
            BigDecimal income=BigDecimal.ZERO;
            BigDecimal profits=null;
            List<BusTeamClassVo> gradeAndSubjectClass=gradeAndSubjectClassVo.getBusTeamClassVoList();
            List<Long> gradeAndSubjectBusTeamIds=BeanUtils.toList(gradeAndSubjectClass,"busTeamId");
            List<ClassIncomeVo> allClassIncomeVoList=businessStatisticsService.classIncomeDetail(gradeAndSubjectBusTeamIds,startDate,endDate);
            Map<Long,List<ClassIncomeVo>> allClassIncomeMap=BeanUtils.toGroup(allClassIncomeVoList,"mainAccountId");
            List<ChangeRecord> allCostList=changeRecordService.findByCategoryIdsAndMainAccountIds(gradeAndSubjectBusTeamIds,0,"cost",startDate,endDate,feeCategoryIdList);
            Map<Long,List<ChangeRecord>> allCostMap=BeanUtils.toGroup(allCostList,"mainAccountId");


            if (gradeAndSubjectClass!=null ){
                for (BusTeamClassVo busTeamClassVo:gradeAndSubjectClass){
                    List<CourseClass> courseClassList=busTeamClassVo.getCourseClassList();
                    List<ClassIncomeVo> classIncomeVoList=allClassIncomeMap.get(busTeamClassVo.getBusTeamId());//businessStatisticsService.classIncomeDetail(Arrays.asList(busTeamClassVo.getBusTeamId()),COURSE_INCOME.id,startDate,endDate);
                    Map<Long,ClassIncomeVo> map=BeanUtils.toMap(classIncomeVoList,"classId");
                    for (CourseClass courseClass:courseClassList){
                        ClassIncomeVo mapClass=map.get(courseClass.getClassId());
                        if (mapClass!=null && mapClass.getSubjectId().equals(courseClass.getSubjectId()) &&mapClass.getGradeId().equals(courseClass.getGradeId())){
                            income=income.add(map.get(courseClass.getClassId()).getTotalIncomeAmount());
                        }
                    }
                    List<ChangeRecord> costList=allCostMap.get(busTeamClassVo.getBusTeamId());//changeRecordService.findByCategoryIdsAndMainAccountIds(Arrays.asList(busTeamClassVo.getBusTeamId()),0,"cost",startDate,endDate,feeCategoryIdList);
                    List<CategoryMainAccountVo> categoryMainAccountVoList=businessStatisticsService.toMainAccountCostList(allFeeCategoryTreeMapVoList,costList,busTeamClassVo.getBusTeamId());
                    if (busTeamClassMap.get(busTeamClassVo.getBusTeamId())!=null){
                        BusTeamClassVo allBusTeamClassVo=busTeamClassMap.get(busTeamClassVo.getBusTeamId());
                        categoryMainAccountVoList=productStatisticsService.calProductCostAlgorithm(allBusTeamClassVo.getClassLectureList(),courseClassList,busTeamClassVo.getBusTeamId(),categoryMainAccountVoList,allBusTeamClassVo.getInTimeTotalLecture(),busTeamClassVo.getInTimeTotalLecture(),startDate,endDate);
                        for(CategoryMainAccountVo categoryMainAccountVo : categoryMainAccountVoList ){
                            cost = cost.add(categoryMainAccountVo.getTotalAmount());
                        }
                    }
                }
            }
            profits=income.subtract(cost);
            gradeAndSubjectCostAndIncomeVo.setCost(cost);
            gradeAndSubjectCostAndIncomeVo.setIncome(income);
            gradeAndSubjectCostAndIncomeVo.setProfits(profits);
            gradeAndSubjectCostAndIncomeVoList.add(gradeAndSubjectCostAndIncomeVo);
        }

        return gradeAndSubjectCostAndIncomeVoList;
    }


    @Override
    public List<GradeAndSubjectCostAndIncomeVo> findCostAndIncomeList(Long areaTeamId, Date startDate, Date endDate, List<Long> gradeIds, List<Long> subjectIds, SysUser sysUser) {
        if (startDate.getTime()>endDate.getTime()){
            throw new BusException("开始时间必须小于等于结束时间");
        }
      /*  String mainAccountFeeCategory = siteConfigService.getConfigValueFromCache("grade_subject_feeCategory");
        List<FeeCategoryTreeMapVo> allFeeCategoryTreeMapVoList = JSONArray.parseArray(mainAccountFeeCategory, FeeCategoryTreeMapVo.class);
*/
        List<GradeAndSubjectCostAndIncomeVo> gradeAndSubjectCostAndIncomeVoList=new ArrayList<GradeAndSubjectCostAndIncomeVo>();
        List<BusTeam> busTeamList=busTeamService.findBusTeamByAreaTeamIds(Arrays.asList(areaTeamId));
        List<Long> busTeamIdList= BeanUtils.toList(busTeamList,"busTeamId");
        busTeamIdList=dataStatisticsService.filterBusTeamByPermissions(busTeamIdList,sysUser.getUserId());
        List<BaseGrade> baseGradeList=null;
        if (Utils.checkListNotEmpty(gradeIds)){
            baseGradeList=baseGradeService.findByIds(gradeIds);
        }else {
            baseGradeList=baseGradeService.findAllFromCache();
            Iterator<BaseGrade> baseGradeIterator=baseGradeList.iterator();
            while (baseGradeIterator.hasNext()){
                BaseGrade baseGrade=baseGradeIterator.next();
                baseGradeIterator.remove();
                baseGradeList.add(baseGrade);
                break;
            }
        }
        List<BaseSubject> baseSubjectList=null;
        if (Utils.checkListNotEmpty(subjectIds)){
            baseSubjectList=baseSubjectService.findByIds(subjectIds);
        }else {
            baseSubjectList=baseSubjectService.findAllFromCache();
        }
        gradeIds=BeanUtils.toList(baseGradeList,"gradeId");
        subjectIds=BeanUtils.toList(baseSubjectList,"subjectId");

        GradeSubjectCostQueryVo gradeSubjectCostQueryVo=new GradeSubjectCostQueryVo();
        gradeSubjectCostQueryVo.setGradeIds(gradeIds);
        gradeSubjectCostQueryVo.setSubjectIds(subjectIds);
        gradeSubjectCostQueryVo.setMainAccountIds(busTeamIdList);
        gradeSubjectCostQueryVo.setStartDate(startDate);
        gradeSubjectCostQueryVo.setEndDate(endDate);
        List<GradeSubjectCostVo> costOfGradeSubjectList=costOfGradeSubjectService.findGradeSubjectCost(gradeSubjectCostQueryVo);

        RealIncomeClassQueryVo realIncomeClassQueryVo=new RealIncomeClassQueryVo();
        realIncomeClassQueryVo.setEndDate(endDate);
        realIncomeClassQueryVo.setStartDate(startDate);
        realIncomeClassQueryVo.setSubjectIds(subjectIds);
        realIncomeClassQueryVo.setBusTeamIds(busTeamIdList);
        realIncomeClassQueryVo.setGradeIds(gradeIds);
        List<GradeSubjectIncomeVo> realIncomeOfClassList=realIncomeOfClassService.findGradeSubjectIncome(realIncomeClassQueryVo);

        Map<Long,List<GradeSubjectCostVo>> costOfGradeMap=BeanUtils.toGroup(costOfGradeSubjectList,"gradeId");
        Map<Long,List<GradeSubjectIncomeVo>> realIncomeOfGradeMap=BeanUtils.toGroup(realIncomeOfClassList,"gradeId");
        for (BaseGrade baseGrade:baseGradeList){
            List<GradeSubjectCostVo> costOfGradeList=costOfGradeMap.get(baseGrade.getGradeId());
            List<GradeSubjectIncomeVo> realIncomeOfGradeList=realIncomeOfGradeMap.get(baseGrade.getGradeId());
            Map<Long,GradeSubjectCostVo> costOfGradeSubjectMap=BeanUtils.toMap(costOfGradeList,"subjectId");
            Map<Long,GradeSubjectIncomeVo> realIncomeOfGradeSubjectMap=BeanUtils.toMap(realIncomeOfGradeList,"subjectId");
            for (BaseSubject baseSubject:baseSubjectList){
                GradeSubjectCostVo gradeSubjectCostVo=costOfGradeSubjectMap.get(baseSubject.getSubjectId());
                GradeSubjectIncomeVo gradeSubjectIncomeVo=realIncomeOfGradeSubjectMap.get(baseSubject.getSubjectId());
                GradeAndSubjectCostAndIncomeVo gradeAndSubjectCostAndIncomeVo=new GradeAndSubjectCostAndIncomeVo();
                gradeAndSubjectCostAndIncomeVo.setGradeId(baseGrade.getGradeId());
                gradeAndSubjectCostAndIncomeVo.setGradeName(baseGrade.getGradeName());
                gradeAndSubjectCostAndIncomeVo.setSubjectId(baseSubject.getSubjectId());
                gradeAndSubjectCostAndIncomeVo.setSubjectName(baseSubject.getSubjectName());
                BigDecimal cost=BigDecimal.ZERO;
                BigDecimal income=BigDecimal.ZERO;
                BigDecimal profits=null;
                if (gradeSubjectCostVo!=null && gradeSubjectCostVo.getAmount()!=null){
                    cost=cost.add(gradeSubjectCostVo.getAmount());
                }
                if (gradeSubjectIncomeVo!=null && gradeSubjectIncomeVo.getAmount()!=null){
                    income=income.add(gradeSubjectIncomeVo.getAmount());
                }
                profits=income.subtract(cost);
                gradeAndSubjectCostAndIncomeVo.setCost(cost);
                gradeAndSubjectCostAndIncomeVo.setIncome(income);
                gradeAndSubjectCostAndIncomeVo.setProfits(profits);
                gradeAndSubjectCostAndIncomeVoList.add(gradeAndSubjectCostAndIncomeVo);
            }
        }
        return gradeAndSubjectCostAndIncomeVoList;
    }

    @Override
    public List<GradeAndSubjectClassVo> findGradeAndSujectBusTeamClassLeature(List<Long> busTeamIdList,List<BaseGrade> baseGradeList, List<BaseSubject> baseSubjectList, Date startDate, Date endDate) {
        List<GradeAndSubjectClassVo> gradeAndSubjectBusTeamClassVoList=new ArrayList<GradeAndSubjectClassVo>();
        List<Long> gradeIdList=BeanUtils.toList(baseGradeList,"gradeId");
        List<Long> subjectIdList=BeanUtils.toList(baseSubjectList,"subjectId");
        List<CourseClass> allGradeAndSubjectCourseClassList=courseClassService.findByBusTeamIdsAndGradesAndSubjects(busTeamIdList,gradeIdList,subjectIdList,"classId","gradeId","subjectId","busTeamId");

        Map<Long,List<CourseClass>> gradeMap=BeanUtils.toGroup(allGradeAndSubjectCourseClassList,"gradeId");
        for (BaseGrade baseGrade:baseGradeList){
            List<CourseClass> gradeCourseClassList=gradeMap.get(baseGrade.getGradeId());
            for (BaseSubject baseSubject:baseSubjectList){
                Map<Long,List<CourseClass>> subjectMap=BeanUtils.toGroup(gradeCourseClassList,"subjectId");
                GradeAndSubjectClassVo gradeAndSubjectBusTeamClassVo=new GradeAndSubjectClassVo();
                gradeAndSubjectBusTeamClassVo.setGradeId(baseGrade.getGradeId());
                gradeAndSubjectBusTeamClassVo.setGradeName(baseGrade.getGradeName());
                gradeAndSubjectBusTeamClassVo.setSubjectId(baseSubject.getSubjectId());
                gradeAndSubjectBusTeamClassVo.setSubjectName(baseSubject.getSubjectName());
                List<CourseClass> gradeAndSubjectCourseClassList=subjectMap.get(baseSubject.getSubjectId());
                List<Long> classIdList = BeanUtils.toList(gradeAndSubjectCourseClassList, "classId");
                List<ClassLecture> classLectureList = classLectureService.findByClassIdAndTime(classIdList, null, null,1,"classId","classDate");
                List<BusTeamClassVo> busTeamClassVoList=productStatisticsService.findBusTeamsClassLeature(busTeamIdList,gradeAndSubjectCourseClassList,classLectureList,startDate,endDate);
                gradeAndSubjectBusTeamClassVo.setBusTeamClassVoList(busTeamClassVoList);
                gradeAndSubjectBusTeamClassVoList.add(gradeAndSubjectBusTeamClassVo);
            }
        }
        return gradeAndSubjectBusTeamClassVoList;
    }

    @Override
    public List<GradeAndSubjectCostByCategoryVo> findCategoryCostByGradeAndSubject(Long areaTeamId,List<FeeCategoryTreeMapVo> feeCategoryTreeMapVoList, Long gradeId, Long subjectId, Date startDate, Date endDate) {
        if (startDate.getTime()>endDate.getTime()){
            throw new BusException("开始时间必须小于等于结束时间");
        }
        List<GradeAndSubjectCostByCategoryVo> gradeAndSubjectCostByCategoryVoList=new ArrayList<GradeAndSubjectCostByCategoryVo>();
        BaseGrade baseGrade=baseGradeService.findById(gradeId);
        BaseSubject baseSubject=baseSubjectService.findById(subjectId);
        List<BusTeam> busTeamList=busTeamService.findBusTeamByAreaTeamIds(Arrays.asList(areaTeamId));
        List<Long> busTeamIdList= BeanUtils.toList(busTeamList,"busTeamId");
        busTeamIdList=productStatisticsService.filterBusTeamByPermissions(busTeamIdList);
        List<GradeAndSubjectClassVo> gradeAndSubjectClassVoList=this.findGradeAndSujectBusTeamClassLeature(busTeamIdList,Arrays.asList(baseGrade),Arrays.asList(baseSubject),startDate,endDate);

        List<CourseClass> allBusTeamClass=courseClassService.findSimpByBusTeamIds(busTeamIdList,"classId","busTeamId");
        List<Long> classIdList = BeanUtils.toList(allBusTeamClass, "classId");
        List<ClassLecture> classLectureList = classLectureService.findByClassIdAndTime(classIdList, startDate, endDate,1,"classId","classDate");
        List<BusTeamClassVo> busTeamClassVoList=productStatisticsService.findBusTeamsClassLeature(busTeamIdList,allBusTeamClass,classLectureList,startDate,endDate);
        Map<Long,BusTeamClassVo> map=BeanUtils.toMap(busTeamClassVoList,"busTeamId");


        List<Long> feeCategoryIdList=new ArrayList<Long>();
        businessStatisticsService.fillAllFeeCategoryId(feeCategoryIdList,feeCategoryTreeMapVoList);


        List<CategoryMainAccountVo> allCategoryMainAccountList=new ArrayList<CategoryMainAccountVo>();
        for (GradeAndSubjectClassVo gradeAndSubjectClassVo:gradeAndSubjectClassVoList){
            List<BusTeamClassVo> gradeAndSubjectBusTeamClassList=gradeAndSubjectClassVo.getBusTeamClassVoList();
            if (gradeAndSubjectBusTeamClassList==null){
                continue;
            }
            for (BusTeamClassVo gradeAndSubjecbusTeamClassVo :gradeAndSubjectBusTeamClassList){
                List<ChangeRecord> costList=changeRecordService.findByCategoryIdsAndMainAccountIds(Arrays.asList(gradeAndSubjecbusTeamClassVo.getBusTeamId()),0,"cost",startDate,endDate,feeCategoryIdList);
                List<CategoryMainAccountVo> categoryMainAccountVoList=businessStatisticsService.toMainAccountCostList(feeCategoryTreeMapVoList,costList,gradeAndSubjecbusTeamClassVo.getBusTeamId());/*业务组对应的成本类型的价格*/
                /*将categoryMainAccountVoList 中的价格重新设置为产品的价格*/
                if (map.containsKey(gradeAndSubjecbusTeamClassVo.getBusTeamId())){
                    categoryMainAccountVoList=productStatisticsService.calProductCostAlgorithm(gradeAndSubjecbusTeamClassVo.getClassLectureList(),gradeAndSubjecbusTeamClassVo.getCourseClassList(),gradeAndSubjecbusTeamClassVo.getBusTeamId(),categoryMainAccountVoList,map.get(gradeAndSubjecbusTeamClassVo.getBusTeamId()).getInTimeTotalLecture(),gradeAndSubjecbusTeamClassVo.getInTimeTotalLecture(),startDate,endDate);
                    if (categoryMainAccountVoList!=null){
                        allCategoryMainAccountList.addAll(categoryMainAccountVoList);
                    }
                }

            }
        }
        Map<Long,List<CategoryMainAccountVo>> resultMap=BeanUtils.toGroup(allCategoryMainAccountList,"categoryId");
        for (FeeCategoryTreeMapVo feeCategoryTreeMapVo:feeCategoryTreeMapVoList){
            BigDecimal totalAmount=BigDecimal.ZERO;
            GradeAndSubjectCostByCategoryVo gradeAndSubjectCostByCategoryVo=new GradeAndSubjectCostByCategoryVo();
            gradeAndSubjectCostByCategoryVo.setCategoryId(feeCategoryTreeMapVo.getFeeCategoryId());
            gradeAndSubjectCostByCategoryVo.setName(feeCategoryTreeMapVo.getName());
            if (resultMap.containsKey(feeCategoryTreeMapVo.getFeeCategoryId())){
                List<CategoryMainAccountVo> tempList=resultMap.get(feeCategoryTreeMapVo.getFeeCategoryId());
                for (CategoryMainAccountVo categoryMainAccountVo:tempList){
                    totalAmount=totalAmount.add(categoryMainAccountVo.getTotalAmount());
                }
            }
            gradeAndSubjectCostByCategoryVo.setTotalAmount(totalAmount);
            if (feeCategoryTreeMapVo.getFeeCategoryId().equals(SALARY_OF_COURSE.id)){
                gradeAndSubjectCostByCategoryVo.setDetailType(2);
            }else if (feeCategoryTreeMapVo.getChildren()==null){
                gradeAndSubjectCostByCategoryVo.setDetailType(0);
            }else if (feeCategoryTreeMapVo.getChildren()!=null){
                gradeAndSubjectCostByCategoryVo.setDetailType(1);
            }
            gradeAndSubjectCostByCategoryVoList.add(gradeAndSubjectCostByCategoryVo);
        }
        return gradeAndSubjectCostByCategoryVoList;
    }

    @Override
    public List<GradeAndSubjectCostByCategoryVo> findCategoryCostByGradeAndSubject(Long areaTeamId, List<FeeCategoryTreeMapVo> feeCategoryTreeMapVoList, List<Long> gradeIds, List<Long> subjectIds, Date startDate, Date endDate, SysUser sysUser) {
        if (startDate.getTime()>endDate.getTime()){
            throw new BusException("开始时间必须小于等于结束时间");
        }
        List<GradeAndSubjectCostByCategoryVo> gradeAndSubjectCostByCategoryVoList=new ArrayList<>();
        List<BusTeam> busTeamList=busTeamService.findBusTeamByAreaTeamIds(Arrays.asList(areaTeamId));
        List<Long> busTeamIdList= BeanUtils.toList(busTeamList,"busTeamId");
        busTeamIdList=dataStatisticsService.filterBusTeamByPermissions(busTeamIdList,sysUser.getUserId());

        List<Long> feeCategoryIdList=new ArrayList<Long>(feeCategoryTreeMapVoList.size() * 10 );
        businessStatisticsService.fillAllFeeCategoryId(feeCategoryIdList,feeCategoryTreeMapVoList);
        List<CostOfGradeSubject> costOfGradeSubjectList=costOfGradeSubjectService.findCostByGradeIdsAndSubjectIdsAndFeeCategoryIds(gradeIds,subjectIds,busTeamIdList,startDate,endDate,feeCategoryIdList);
        List<BaseGrade> baseGradeList = null;
        if (Utils.checkListNotEmpty(gradeIds)){
            baseGradeList=baseGradeService.findDealOtherPosition(gradeIds);
        }else {
            baseGradeList=baseGradeService.findAllOrderGrade();
        }
        List<BaseSubject> baseSubjectList = null;
        if (Utils.checkListNotEmpty(subjectIds)){
            baseSubjectList=baseSubjectService.findByIds(subjectIds);
        }else {
            baseSubjectList=baseSubjectService.findAllFromCache();
        }
        Map<Long,List<CostOfGradeSubject>> costOfGradeMap=BeanUtils.toGroup(costOfGradeSubjectList,"gradeId");
        for (BaseGrade baseGrade:baseGradeList){
            List<CostOfGradeSubject> costOfGradeList=costOfGradeMap.get(baseGrade.getGradeId());
            Map<Long,List<CostOfGradeSubject>> costOfGradeSubjectMap=BeanUtils.toGroup(costOfGradeList,"subjectId");
            for (BaseSubject baseSubject:baseSubjectList){
               List<GradeAndSubjectCostByCategoryVo> temp=buildGradeAndSubjectCost(feeCategoryTreeMapVoList,costOfGradeSubjectMap.get(baseSubject.getSubjectId()),baseGrade,baseSubject);
               if (Utils.checkListNotEmpty(temp)){
                   gradeAndSubjectCostByCategoryVoList.addAll(temp);
               }
            }
        }
        return gradeAndSubjectCostByCategoryVoList;
    }

    private List<GradeAndSubjectCostByCategoryVo> buildGradeAndSubjectCost(List<FeeCategoryTreeMapVo> feeCategoryTreeMapVoList,List<CostOfGradeSubject> costOfGradeSubjectList,BaseGrade baseGrade,BaseSubject baseSubject){
        List<GradeAndSubjectCostByCategoryVo> gradeAndSubjectCostByCategoryVoList=new ArrayList<GradeAndSubjectCostByCategoryVo>();

        for (FeeCategoryTreeMapVo feeCategoryTreeMapVo:feeCategoryTreeMapVoList){
            Map<Long,List<CostOfGradeSubject>> costFeeCategoryMap = BeanUtils.toGroup(costOfGradeSubjectList,"feeCategoryId");

            BigDecimal totalAmount=BigDecimal.ZERO;
            GradeAndSubjectCostByCategoryVo gradeAndSubjectCostByCategoryVo=new GradeAndSubjectCostByCategoryVo();
            gradeAndSubjectCostByCategoryVo.setCategoryId(feeCategoryTreeMapVo.getFeeCategoryId());
            gradeAndSubjectCostByCategoryVo.setName(feeCategoryTreeMapVo.getName());
            gradeAndSubjectCostByCategoryVo.setSubjectId(baseSubject.getSubjectId());
            gradeAndSubjectCostByCategoryVo.setSubjectName(baseSubject.getSubjectName());
            gradeAndSubjectCostByCategoryVo.setGradeName(baseGrade.getGradeName());
            gradeAndSubjectCostByCategoryVo.setGradeId(baseGrade.getGradeId());
            if (costFeeCategoryMap.containsKey(feeCategoryTreeMapVo.getFeeCategoryId())){
                List<CostOfGradeSubject> tempList=costFeeCategoryMap.get(feeCategoryTreeMapVo.getFeeCategoryId());
                for (CostOfGradeSubject costOfGradeSubject:tempList){
                    totalAmount=totalAmount.add(costOfGradeSubject.getAmount());
                }
            }
            if (feeCategoryTreeMapVo.getChildren()!=null){
                totalAmount=this.countChirldAmount(feeCategoryTreeMapVo.getChildren(),costFeeCategoryMap);
            }
            gradeAndSubjectCostByCategoryVo.setTotalAmount(totalAmount);
            if (feeCategoryTreeMapVo.getFeeCategoryId().equals(SALARY_OF_COURSE.id)){
                gradeAndSubjectCostByCategoryVo.setDetailType(2);
            }else if (feeCategoryTreeMapVo.getChildren()==null){
                gradeAndSubjectCostByCategoryVo.setDetailType(0);
            }else if (feeCategoryTreeMapVo.getChildren()!=null){
                gradeAndSubjectCostByCategoryVo.setDetailType(1);
            }
            gradeAndSubjectCostByCategoryVoList.add(gradeAndSubjectCostByCategoryVo);
        }
        return  gradeAndSubjectCostByCategoryVoList;
    }

    private BigDecimal countChirldAmount(List<FeeCategoryTreeMapVo> allFeeCategoryTreeMapVoList,Map<Long,List<CostOfGradeSubject>> categoryId2CostOfProduct){
        BigDecimal totalAmount=BigDecimal.ZERO;
        for (FeeCategoryTreeMapVo feeCategoryTreeMapVo:allFeeCategoryTreeMapVoList){
            if (categoryId2CostOfProduct.containsKey(feeCategoryTreeMapVo.getFeeCategoryId())){
                List<CostOfGradeSubject> tempList=categoryId2CostOfProduct.get(feeCategoryTreeMapVo.getFeeCategoryId());
                for (CostOfGradeSubject costOfProduct:tempList){
                    totalAmount=totalAmount.add(costOfProduct.getAmount());
                }
            }
            if (feeCategoryTreeMapVo.getChildren()!=null){
                totalAmount=totalAmount.add(countChirldAmount(feeCategoryTreeMapVo.getChildren(),categoryId2CostOfProduct));
            }
        }
        return totalAmount;
    }

    @Override
    public List<TeacherClassCostVo> gradeAndSubjectClassRemunerationDetail(Long areaTeamId,Long gradeId, Long subjectId, Long feeCategoryId, Date startDate, Date endDate) {

        List<TeacherClassCostVo> gradeAndSubjectTeacherClassCostVoList=new ArrayList<TeacherClassCostVo>();
        BaseGrade baseGrade=baseGradeService.findById(gradeId);
        BaseSubject baseSubject=baseSubjectService.findById(subjectId);
        List<BusTeam> busTeamList=busTeamService.findBusTeamByAreaTeamIds(Arrays.asList(areaTeamId));
        List<Long> busTeamIdList= BeanUtils.toList(busTeamList,"busTeamId");
        busTeamIdList=productStatisticsService.filterBusTeamByPermissions(busTeamIdList);
        List<GradeAndSubjectClassVo> gradeAndSubjectClassVoList=this.findGradeAndSujectBusTeamClassLeature(busTeamIdList,Arrays.asList(baseGrade),Arrays.asList(baseSubject),startDate,endDate);
        for (GradeAndSubjectClassVo gradeAndSubjectClassVo:gradeAndSubjectClassVoList){
            List<BusTeamClassVo> busTeamClassVoList=gradeAndSubjectClassVo.getBusTeamClassVoList();
            for (BusTeamClassVo busTeamClassVo:busTeamClassVoList){
                List<TeacherClassCostVo> teacherClassCostVoList=businessStatisticsService.classRemunerationDetail(busTeamClassVo.getBusTeamId(),SALARY_OF_COURSE.id,startDate,endDate);
                Map<Long,List<TeacherClassCostVo>> map=BeanUtils.toGroup(teacherClassCostVoList,"classId");
                for (CourseClass courseClass:busTeamClassVo.getCourseClassList()){
                    List<TeacherClassCostVo> tempTeacherClassCostVos=map.get(courseClass.getClassId());
                    if (tempTeacherClassCostVos!=null){
                        gradeAndSubjectTeacherClassCostVoList.addAll(tempTeacherClassCostVos);
                    }
                }
            }
        }
        return gradeAndSubjectTeacherClassCostVoList;
    }

    @Override
    public List<TeacherClassCostVo> gradeAndSubjectClassRemunerationDetail(Long areaTeamId, Long gradeId, Long subjectId, Long feeCategoryId, Date startDate, Date endDate, SysUser sysUser) {

        List<TeacherClassCostVo> productTeacherClassCostVoList=new ArrayList<TeacherClassCostVo>();
        List<Long> busTeamIds=dataStatisticsService.findPermissionBusTeam(Arrays.asList(areaTeamId),sysUser.getUserId());

        List<CostOfGradeSubject> costOfGradeSubjectList=costOfGradeSubjectService.findCostByGradeIdsAndSubjectIdsAndFeeCategoryIds(Arrays.asList(gradeId),Arrays.asList(subjectId),busTeamIds,startDate,endDate,Arrays.asList(feeCategoryId));

        for (CostOfGradeSubject costOfGradeSubject:costOfGradeSubjectList){
            TeacherClassCostVo teacherClassCostVo=new TeacherClassCostVo();
            teacherClassCostVo.setClassHour(2);
            teacherClassCostVo.setTotalClassRemuneration(costOfGradeSubject.getAmount());
            teacherClassCostVo.setSettlementDate(costOfGradeSubject.getCreateTime());
            teacherClassCostVo.setClassRemuneration(costOfGradeSubject.getAmount().divide(new BigDecimal(2)));
            String extraString=costOfGradeSubject.getExtra();
            Extra extra= JSONObject.parseObject(extraString,Extra.class);
            if (extra!=null ){
                teacherClassCostVo.setTeacherId(extra.getTeacherId());
                teacherClassCostVo.setTeacherName(extra.getTeacherName());
                teacherClassCostVo.setIdNo(extra.getIdNo());
                teacherClassCostVo.setPhoneNo(extra.getPhone());
                teacherClassCostVo.setClassId(extra.getClassId());
                teacherClassCostVo.setClassName(extra.getClassName());
                teacherClassCostVo.setAreaTeamName(extra.getAreaTeamName());
                teacherClassCostVo.setBusTeamName(extra.getBusTeamName());
                teacherClassCostVo.setLectureNo(extra.getLectureNo());
            }
            productTeacherClassCostVoList.add(teacherClassCostVo);
        }
        return productTeacherClassCostVoList;
    }

    @Override
    public Page<TeacherClassCostVo> gradeAndSubjectClassRemunerationPage(Long areaTeamId, Long gradeId, Long subjectId, Long feeCategoryId, Date startDate, Date endDate, SysUser sysUser, int pageNo, int pageSize) {
        List<Long> busTeamIds=dataStatisticsService.findPermissionBusTeam(Arrays.asList(areaTeamId),sysUser.getUserId());

        GradeSubjectCostQueryVo gradeSubjectCostQueryVo=new GradeSubjectCostQueryVo();
        gradeSubjectCostQueryVo.setMainAccountIds(busTeamIds);
        gradeSubjectCostQueryVo.setEndDate(endDate);
        gradeSubjectCostQueryVo.setGradeId(gradeId);
        gradeSubjectCostQueryVo.setSubjectId(subjectId);
        gradeSubjectCostQueryVo.setFeeCategoryId(feeCategoryId);
        Page<CostOfGradeSubject> costOfGradeSubjectPage=costOfGradeSubjectService.findGradeSubjectCostPage(gradeSubjectCostQueryVo,pageNo,pageSize);

        Page<TeacherClassCostVo> teacherClassCostVoPage=Utils.newPage(costOfGradeSubjectPage);
        List<CostOfGradeSubject> costOfGradeSubjectList=costOfGradeSubjectPage.getRecords();
        if (costOfGradeSubjectList!=null){
            List<TeacherClassCostVo> teacherClassCostVoList=new ArrayList<TeacherClassCostVo>(costOfGradeSubjectList.size());
            for (CostOfGradeSubject costOfGradeSubject:costOfGradeSubjectList){
                TeacherClassCostVo teacherClassCostVo=new TeacherClassCostVo();
                teacherClassCostVo.setClassHour(2);
                teacherClassCostVo.setTotalClassRemuneration(costOfGradeSubject.getAmount());
                teacherClassCostVo.setSettlementDate(costOfGradeSubject.getCreateTime());
                teacherClassCostVo.setClassRemuneration(costOfGradeSubject.getAmount().divide(new BigDecimal(2)));
                String extraString=costOfGradeSubject.getExtra();
                Extra extra= JSONObject.parseObject(extraString,Extra.class);
                if (extra!=null ){
                    teacherClassCostVo.setTeacherId(extra.getTeacherId());
                    teacherClassCostVo.setTeacherName(extra.getTeacherName());
                    teacherClassCostVo.setIdNo(extra.getIdNo());
                    teacherClassCostVo.setPhoneNo(extra.getPhone());
                    teacherClassCostVo.setClassId(extra.getClassId());
                    teacherClassCostVo.setClassName(extra.getClassName());
                    teacherClassCostVo.setAreaTeamName(extra.getAreaTeamName());
                    teacherClassCostVo.setBusTeamName(extra.getBusTeamName());
                    teacherClassCostVo.setLectureNo(extra.getLectureNo());
                }
                teacherClassCostVoList.add(teacherClassCostVo);

            }
            teacherClassCostVoPage.setRecords(teacherClassCostVoList);
        }
        return teacherClassCostVoPage;
    }

    @Override
    public GradeAndSubjectCostDetailVo findDetail(Long areaTeamId,Integer detailType, Long feeCategoryId, Long gradeId, Long subjectId, Date startDate, Date endDate) {
        if (startDate.getTime()>endDate.getTime()){
            throw new BusException("开始时间必须小于等于结束时间");
        }
        GradeAndSubjectCostDetailVo gradeAndSubjectCostDetailVo=new GradeAndSubjectCostDetailVo();
        if (detailType==0){//明细

        }else if (detailType==1){//子类型
            String mainAccountFeeCategory = siteConfigService.getConfigValueFromCache("grade_subject_feeCategory");
            List<FeeCategoryTreeMapVo> allFeeCategoryTreeMapVoList = JSONArray.parseArray(mainAccountFeeCategory, FeeCategoryTreeMapVo.class);
            List<FeeCategoryTreeMapVo> feeCategoryTreeMapVoList=businessStatisticsService.findChildListByParentId(allFeeCategoryTreeMapVoList,feeCategoryId);
            List<GradeAndSubjectCostByCategoryVo> gradeAndSubjectCostByCategoryVoList=this.findCategoryCostByGradeAndSubject(areaTeamId,feeCategoryTreeMapVoList,gradeId,subjectId,startDate,endDate);
            gradeAndSubjectCostDetailVo.setGradeAndSubjectCostByCategoryVoList(gradeAndSubjectCostByCategoryVoList);
        }else if (detailType==2){//课酬
            List<TeacherClassCostVo> teacherClassCostVoList=this.gradeAndSubjectClassRemunerationDetail(areaTeamId,gradeId,subjectId,feeCategoryId,startDate,endDate);
            gradeAndSubjectCostDetailVo.setTeacherClassCostVoList(teacherClassCostVoList);
        }
        return gradeAndSubjectCostDetailVo;
    }

    @Override
    public GradeAndSubjectCostDetailVo findDetail(Long areaTeamId, Integer detailType, Long feeCategoryId, Long gradeId, Long subjectId, Date startDate, Date endDate, SysUser sysUser) {
        if (startDate.getTime()>endDate.getTime()){
            throw new BusException("开始时间必须小于等于结束时间");
        }
        GradeAndSubjectCostDetailVo gradeAndSubjectCostDetailVo=new GradeAndSubjectCostDetailVo();
        if (detailType==0){//明细

        }else if (detailType==1){//子类型
            String mainAccountFeeCategory = siteConfigService.getConfigValueFromCache("grade_subject_feeCategory");
            List<FeeCategoryTreeMapVo> allFeeCategoryTreeMapVoList = JSONArray.parseArray(mainAccountFeeCategory, FeeCategoryTreeMapVo.class);
            List<FeeCategoryTreeMapVo> feeCategoryTreeMapVoList=businessStatisticsService.findChildListByParentId(allFeeCategoryTreeMapVoList,feeCategoryId);
            List<GradeAndSubjectCostByCategoryVo> gradeAndSubjectCostByCategoryVoList=this.findCategoryCostByGradeAndSubject(areaTeamId,feeCategoryTreeMapVoList,Arrays.asList(gradeId),Arrays.asList(subjectId),startDate,endDate,sysUser);
            gradeAndSubjectCostDetailVo.setGradeAndSubjectCostByCategoryVoList(gradeAndSubjectCostByCategoryVoList);
        }else if (detailType==2){//课酬
            List<TeacherClassCostVo> teacherClassCostVoList=this.gradeAndSubjectClassRemunerationDetail(areaTeamId,gradeId,subjectId,feeCategoryId,startDate,endDate,sysUser);
            gradeAndSubjectCostDetailVo.setTeacherClassCostVoList(teacherClassCostVoList);
        }
        return gradeAndSubjectCostDetailVo;
    }

    @Override
    public GradeAndSubjectCostDetailVo findGradeAndSubjectDetail(Long areaTeamId, Integer detailType, Long feeCategoryId, Long gradeId, Long subjectId, Date startDate, Date endDate, SysUser sysUser,int pageNo,int pageSize) {
        if (startDate.getTime()>endDate.getTime()){
            throw new BusException("开始时间必须小于等于结束时间");
        }
        GradeAndSubjectCostDetailVo gradeAndSubjectCostDetailVo=new GradeAndSubjectCostDetailVo();
        if (detailType==0){//明细

        }else if (detailType==1){//子类型
            String mainAccountFeeCategory = siteConfigService.getConfigValueFromCache("grade_subject_feeCategory");
            List<FeeCategoryTreeMapVo> allFeeCategoryTreeMapVoList = JSONArray.parseArray(mainAccountFeeCategory, FeeCategoryTreeMapVo.class);
            List<FeeCategoryTreeMapVo> feeCategoryTreeMapVoList=businessStatisticsService.findChildListByParentId(allFeeCategoryTreeMapVoList,feeCategoryId);
            List<GradeAndSubjectCostByCategoryVo> gradeAndSubjectCostByCategoryVoList=this.findCategoryCostByGradeAndSubject(areaTeamId,feeCategoryTreeMapVoList,Arrays.asList(gradeId),Arrays.asList(subjectId),startDate,endDate,sysUser);
            gradeAndSubjectCostDetailVo.setGradeAndSubjectCostByCategoryVoList(gradeAndSubjectCostByCategoryVoList);
        }else if (detailType==2){//课酬
            Page<TeacherClassCostVo> teacherClassCostVoPage=this.gradeAndSubjectClassRemunerationPage(areaTeamId,gradeId,subjectId,feeCategoryId,startDate,endDate,sysUser,pageNo,pageSize);
            gradeAndSubjectCostDetailVo.setTeacherClassCostVoPage(teacherClassCostVoPage);
        }
        return gradeAndSubjectCostDetailVo;
    }

    @Override
    public List<ClassIncomeVo> findClassIncomeByAreaTeamId(Long areaTeamId, Long gradeId, Long subjectId, Date startDate, Date endDate) {
        if (startDate.getTime()>endDate.getTime()){
            throw new BusException("开始时间必须小于等于结束时间");
        }
        BaseGrade baseGrade=baseGradeService.findById(gradeId);
        BaseSubject baseSubject=baseSubjectService.findById(subjectId);
        List<BusTeam> busTeamList=busTeamService.findBusTeamByAreaTeamIds(Arrays.asList(areaTeamId));
        List<Long> busTeamIdList= BeanUtils.toList(busTeamList,"busTeamId");
        busTeamIdList=productStatisticsService.filterBusTeamByPermissions(busTeamIdList);
        List<GradeAndSubjectClassVo> gradeAndSubjectClassVoList=this.findGradeAndSujectBusTeamClassLeature(busTeamIdList,Arrays.asList(baseGrade),Arrays.asList(baseSubject),startDate,endDate);
        List<ClassIncomeVo> allClassIncome=new ArrayList<ClassIncomeVo>();
        for (GradeAndSubjectClassVo gradeAndSubjectClassVo:gradeAndSubjectClassVoList){
            List<BusTeamClassVo> busTeamClassVoList=gradeAndSubjectClassVo.getBusTeamClassVoList();
            for (BusTeamClassVo busTeamClassVo:busTeamClassVoList){
                List<ClassIncomeVo> classIncomeVoList=businessStatisticsService.classIncomeDetail(Arrays.asList(busTeamClassVo.getBusTeamId()),startDate,endDate);
                for (ClassIncomeVo classIncomeVo:classIncomeVoList){
                    if (gradeId.equals(classIncomeVo.getGradeId()) && subjectId.equals(classIncomeVo.getSubjectId())){
                        allClassIncome.add(classIncomeVo);
                    }
                }
            }
        }
        return allClassIncome;
    }

    @Override
    public List<ClassIncomeVo> findClassIncomeByAreaTeamId(Long areaTeamId, Long gradeId, Long subjectId, Date startDate, Date endDate, SysUser sysUser) {
        if (startDate.getTime()>endDate.getTime()){
            throw new BusException("开始时间必须小于等于结束时间");
        }

        List<ClassIncomeVo> classIncomeVoList=new ArrayList<>();

        List<Long> busTeamIds=dataStatisticsService.findPermissionBusTeam(Arrays.asList(areaTeamId),sysUser.getUserId());

        List<RealIncomeOfClass> realIncomeOfClassList=realIncomeOfClassService.findRealIncomeOfClassByBusTeamIdsGradeIdsSubjectIds(busTeamIds,Arrays.asList(gradeId),Arrays.asList(subjectId),startDate,endDate);

        Map<Long,List<RealIncomeOfClass>> map=BeanUtils.toGroup(realIncomeOfClassList,"classId");
        List<Long> classIdList=BeanUtils.toList(realIncomeOfClassList,"classId");

        classIdList= Utils.removeDuplicate(classIdList);

        List<CourseClass> courseClassList=courseClassService.findByIds(classIdList,"classId","className","busTeamId","busTeamName","areaTeamId","areaTeamName","gradeId","gradeName","subjectId","subjectName","lectureAmount","studyingFee","regAmount","productId","periodId");

        List<StudentReg> studentRegList=studentRegService.findListByClassIds(classIdList,0,"classId","payAmount","refundAmount");
        Map<Long,List<StudentReg>> regMap=BeanUtils.toGroup(studentRegList,"classId");
        for (CourseClass courseClass:courseClassList){
            ClassIncomeVo classIncomeVo=new ClassIncomeVo();
            classIncomeVo.setClassId(courseClass.getClassId());
            classIncomeVo.setGradeId(courseClass.getGradeId());
            classIncomeVo.setGradeName(courseClass.getGradeName());
            classIncomeVo.setSubjectId(courseClass.getSubjectId());
            classIncomeVo.setSubjectName(courseClass.getSubjectName());
            classIncomeVo.setClassName(courseClass.getClassName());
            classIncomeVo.setLectureAmount(courseClass.getLectureAmount());
            classIncomeVo.setStudyingFee(courseClass.getStudyingFee());
            classIncomeVo.setPeriodId(courseClass.getPeriodId());
            classIncomeVo.setRegAmount(courseClass.getRegAmount());
            classIncomeVo.setAreaTeamId(courseClass.getAreaTeamId());
            classIncomeVo.setAreaTeamName(courseClass.getAreaTeamName());
            classIncomeVo.setBusTeamId(courseClass.getBusTeamId());
            classIncomeVo.setBusTeamName(courseClass.getBusTeamName());
            classIncomeVo.setProductId(courseClass.getProductId());
            classIncomeVo.setMainAccountId(courseClass.getBusTeamId());
            classIncomeVo.setStudyingFee(courseClass.getStudyingFee());
            classIncomeVo.setCompletedLectureAmount(courseClass.getCompletedLectureAmount());
            BigDecimal advanceAmount=BigDecimal.ZERO;
            List<StudentReg> oneStudentRegList=regMap.get(courseClass.getClassId());
            if (oneStudentRegList!=null){
                for (StudentReg studentReg:oneStudentRegList){
                    advanceAmount=advanceAmount.add(studentReg.getPayAmount().subtract(studentReg.getRefundAmount()));
                }
            }
            classIncomeVo.setAdvanceAmount(advanceAmount);

            List<RealIncomeOfClass> realIncomeOfOneClassList=map.get(courseClass.getClassId());
            if (realIncomeOfOneClassList!=null){
                Set<Long> lectureSet=new HashSet<>();
                BigDecimal totalAmount=BigDecimal.ZERO;
                for (RealIncomeOfClass realIncomeOfClass:realIncomeOfOneClassList){
                    lectureSet.add(realIncomeOfClass.getLectureId());
                    totalAmount=totalAmount.add(realIncomeOfClass.getAmount());
                }
                classIncomeVo.setHappenLectureAmount(lectureSet.size());
                classIncomeVo.setTotalIncomeAmount(totalAmount);
            }
            classIncomeVoList.add(classIncomeVo);
        }
        return classIncomeVoList;
    }

    @Override
    public Page<ClassIncomeVo> findClassIncomePageByAreaTeamId(Long areaTeamId, List<Long> gradeIds, List<Long> subjectIds, Date startDate, Date endDate, SysUser sysUser,int pageNo,int pageSize) {
        if (startDate.getTime()>endDate.getTime()){
            throw new BusException("开始时间必须小于等于结束时间");
        }
        List<Long> busTeamIds=dataStatisticsService.findPermissionBusTeam(Arrays.asList(areaTeamId),sysUser.getUserId());
        CourseClassQueryVo courseClassQueryVo=new CourseClassQueryVo();
        courseClassQueryVo.setGradeIds(gradeIds);
        courseClassQueryVo.setSubjectIds(subjectIds);
        courseClassQueryVo.setBusTeamIds(busTeamIds);
        Page<CourseClass> courseClassPage=courseClassService.findCourseClassByQuery(courseClassQueryVo,pageNo,pageSize);
        Page<ClassIncomeVo> classIncomeVoPage= Utils.newPage(courseClassPage);
        List<CourseClass> courseClassList=courseClassPage.getRecords();
        if (courseClassList!=null && courseClassList.size()>0){
            List<ClassIncomeVo> classIncomeVoList=new ArrayList<>(courseClassList.size());
            List<Long> classIds=BeanUtils.toList(courseClassList,"classId");
            List<StudentReg> studentRegList=studentRegService.findListByClassIds(classIds,0,"classId","payAmount","refundAmount");
            Map<Long,List<StudentReg>> regMap=BeanUtils.toGroup(studentRegList,"classId");

            RealIncomeClassQueryVo realIncomeClassQueryVo=new RealIncomeClassQueryVo();
            realIncomeClassQueryVo.setStartDate(startDate);
            realIncomeClassQueryVo.setEndDate(endDate);
            realIncomeClassQueryVo.setClassIds(classIds);
            List<ClassAmountVo> classAmountVoList=realIncomeOfClassService.findClassAmount(realIncomeClassQueryVo);
            Map<Long,ClassAmountVo> map=BeanUtils.toMap(classAmountVoList,"classId");
            for (CourseClass courseClass:courseClassList){
                ClassIncomeVo classIncomeVo=new ClassIncomeVo();
                BeanUtils.copyProperties(classIncomeVo,courseClass);
                classIncomeVo.setMainAccountId(courseClass.getBusTeamId());
                ClassAmountVo classAmountVo=map.get(courseClass.getClassId());
                if (classAmountVo!=null){
                    classIncomeVo.setHappenLectureAmount(classAmountVo.getHappenLectureAmount());
                    classIncomeVo.setTotalIncomeAmount(classAmountVo.getAmount());
                }
                BigDecimal advanceAmount=BigDecimal.ZERO;
                List<StudentReg> oneStudentRegList=regMap.get(courseClass.getClassId());
                if (oneStudentRegList!=null){
                    for (StudentReg studentReg:oneStudentRegList){
                        advanceAmount=advanceAmount.add(studentReg.getPayAmount().subtract(studentReg.getRefundAmount()));
                    }
                }
                classIncomeVo.setAdvanceAmount(advanceAmount);

                classIncomeVoList.add(classIncomeVo);
            }
            classIncomeVoPage.setRecords(classIncomeVoList);
        }
        return classIncomeVoPage;

    }
}